<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.png">
  <link rel="mask-icon" href="/images/favicon.png" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/font-awesome.min.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css">


<script id="hexo-configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    hostname: new URL('https://codz-me.vercel.app').hostname,
    root: '/',
    scheme: 'Muse',
    version: '7.7.1',
    exturl: false,
    sidebar: {"position":"right","display":"post","padding":18,"offset":12,"onmobile":false},
    copycode: {"enable":false,"show_result":false,"style":null},
    back2top: {"enable":true,"sidebar":false,"scrollpercent":false},
    bookmark: {"enable":false,"color":"#222","save":"auto"},
    fancybox: true,
    mediumzoom: false,
    lazyload: false,
    pangu: false,
    comments: {"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},
    algolia: {
      appID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    },
    localsearch: {"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},
    path: '',
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}
  };
</script>

  <meta name="description" content="OpenSSL安装 OpenSSL官网，或者参考 linux升级OpenSSL 中间可能会遇到 openssl.cnf 的问题，请使用 openssl-1.0.1t.tar.gz 包 apps下的 demoCA 和 openssl.cnf  证书生成  单向认证，参考 Nginx单向认证的安装配置 12345678910111213141516openssl genrsa -des3 -out">
<meta property="og:type" content="article">
<meta property="og:title" content="HTTPS 证书生成 &amp; Nginx&#x2F;Tomcat 配置 HTTPS">
<meta property="og:url" content="https://codz-me.vercel.app/2016/08/12/nginx-tomcat-config-https/index.html">
<meta property="og:site_name" content="Code Is Poetry">
<meta property="og:description" content="OpenSSL安装 OpenSSL官网，或者参考 linux升级OpenSSL 中间可能会遇到 openssl.cnf 的问题，请使用 openssl-1.0.1t.tar.gz 包 apps下的 demoCA 和 openssl.cnf  证书生成  单向认证，参考 Nginx单向认证的安装配置 12345678910111213141516openssl genrsa -des3 -out">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2016-08-12T13:44:00.000Z">
<meta property="article:modified_time" content="2017-02-20T00:48:31.000Z">
<meta property="article:author" content="laudukang">
<meta property="article:tag" content="web">
<meta name="twitter:card" content="summary">

<link rel="canonical" href="https://codz-me.vercel.app/2016/08/12/nginx-tomcat-config-https/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome: false,
    isPost: true
  };
</script>

  <title>HTTPS 证书生成 & Nginx/Tomcat 配置 HTTPS | Code Is Poetry</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-meta">

    <div>
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Code Is Poetry</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
  </div>

  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>
</div>


<nav class="site-nav">
  
  <ul id="menu" class="menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="fa fa-fw fa-home"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="fa fa-fw fa-user"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="fa fa-fw fa-tags"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="fa fa-fw fa-th"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="fa fa-fw fa-archive"></i>归档</a>

  </li>
        <li class="menu-item menu-item-commonweal">

    <a href="/404/" rel="section"><i class="fa fa-fw fa-heartbeat"></i>公益 404</a>

  </li>
  </ul>

</nav>
</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content">
            

  <div class="posts-expand">
      
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block " lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://codz-me.vercel.app/2016/08/12/nginx-tomcat-config-https/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/head.png">
      <meta itemprop="name" content="laudukang">
      <meta itemprop="description" content="Bug Not Found">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Code Is Poetry">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          HTTPS 证书生成 & Nginx/Tomcat 配置 HTTPS
        </h1>

        <div class="post-meta">
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="fa fa-calendar-check-o"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2017-02-20 08:48:31 08:48:31" itemprop="dateModified" datetime="2017-02-20T08:48:31+08:00">2017-02-20 08:48:31</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Web/" itemprop="url" rel="index">
                    <span itemprop="name">Web</span>
                  </a>
                </span>
            </span>

          
            <span id="/2016/08/12/nginx-tomcat-config-https/" class="post-meta-item leancloud_visitors" data-flag-title="HTTPS 证书生成 & Nginx/Tomcat 配置 HTTPS" title="阅读次数">
                <span hidden class="leancloud-visitors-count"></span>
            </span>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <ol>
<li><p>OpenSSL安装</p>
<p>OpenSSL官网，或者参考 linux升级OpenSSL</p>
<p>中间可能会遇到 openssl.cnf 的问题，请使用 openssl-1.0.1t.tar.gz 包 apps下的 demoCA 和 openssl.cnf</p>
</li>
<li><p>证书生成</p>
<ul>
<li><p>单向认证，参考 Nginx单向认证的安装配置</p>
<figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">openssl genrsa -des3 -<span class="keyword">out</span> <span class="keyword">server</span>.key <span class="number">2048</span> #自定义密码</span><br><span class="line"></span><br><span class="line">openssl req -<span class="built_in">new</span> -key <span class="keyword">server</span>.key -<span class="keyword">out</span> <span class="keyword">server</span>.csr</span><br><span class="line"></span><br><span class="line">#<span class="comment">---------------------------------------------------------------------------------------------------------------</span></span><br><span class="line">Enter pass phrase <span class="keyword">for</span> <span class="keyword">server</span>.key: 自定义密码</span><br><span class="line">Country <span class="type">Name</span> (<span class="number">2</span> letter code) [XX]: CN                                           #国家</span><br><span class="line">State <span class="keyword">or</span> Province <span class="type">Name</span> (<span class="keyword">full</span> <span class="type">name</span>) []: GD                                       #区域或是省份</span><br><span class="line">Locality <span class="type">Name</span> (eg, city) [<span class="keyword">Default</span> City]: SZ                                     #地区局部名字</span><br><span class="line">Organization <span class="type">Name</span> (eg, company) [<span class="keyword">Default</span> Company Ltd]: Test                     #机构名称：填写公司名</span><br><span class="line">Organizational Unit <span class="type">Name</span> (eg, section) []: Test                                 #组织单位名称:部门名称</span><br><span class="line">Common <span class="type">Name</span> (eg, your <span class="type">name</span> <span class="keyword">or</span> your <span class="keyword">server</span><span class="string">'s hostname) []: *.domain.com          #网站域名</span></span><br><span class="line"><span class="string">Email Address []: admin@domain.com                                              #邮箱地址</span></span><br><span class="line"><span class="string">A challenge password []:                                                        #输入一个密码</span></span><br><span class="line"><span class="string">An optional company name []:                                                    #一个可选的公司名称</span></span><br><span class="line"><span class="string">#---------------------------------------------------------------------------------------------------------------</span></span><br></pre></td></tr></table></figure>

<blockquote><p>怎么让nginx配置SSL安全证书重启免输入密码，不然Nginx、Tomcat使用该私钥启动的时候需要输入上面的密钥</p>
<p>openssl rsa -in server.key -out server.key.unsecure<br>openssl x509 -req -days 365 -in server.csr -signkey server.key.unsecure -out server.crt  #使用上面的密钥和CSR对证书进行签名</p>
</blockquote>
</li>
<li><p>双向认证，参考 openssl生成SSL证书的流程</p>
<p>CA根证书的生成</p>
<figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># <span class="keyword">Generate</span> <span class="keyword">CA</span> private key   </span><br><span class="line">openssl genrsa -<span class="keyword">out</span> <span class="keyword">ca</span>.key 2048   </span><br><span class="line"># <span class="keyword">Generate</span> CSR   </span><br><span class="line">openssl req -new -key <span class="keyword">ca</span>.key -<span class="keyword">out</span> <span class="keyword">ca</span>.csr  </span><br><span class="line"># <span class="keyword">Generate</span> Self Signed certificate（<span class="keyword">CA</span> 根证书）  </span><br><span class="line">openssl x509 -req -days 365 -<span class="keyword">in</span> <span class="keyword">ca</span>.csr -signkey <span class="keyword">ca</span>.key -<span class="keyword">out</span> <span class="keyword">ca</span>.crt</span><br></pre></td></tr></table></figure>

<p>用户证书的生成</p>
<figure class="highlight axapta"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"># 服务器端用户证书</span></span><br><span class="line"><span class="meta"># private key  </span></span><br><span class="line">openssl genrsa -des3 -out <span class="keyword">server</span>.key <span class="number">1024</span>   </span><br><span class="line"><span class="meta"># generate csr  </span></span><br><span class="line">openssl req -<span class="keyword">new</span> -key <span class="keyword">server</span>.key -out <span class="keyword">server</span>.csr  </span><br><span class="line"><span class="meta"># generate certificate  </span></span><br><span class="line">openssl ca -in <span class="keyword">server</span>.csr -out <span class="keyword">server</span>.crt -cert ca.crt -keyfile ca.key  </span><br><span class="line"></span><br><span class="line"><span class="meta"># 客户端用户证书</span></span><br><span class="line">openssl genrsa -des3 -out <span class="keyword">client</span>.key <span class="number">1024</span>   </span><br><span class="line">openssl req -<span class="keyword">new</span> -key <span class="keyword">client</span>.key -out <span class="keyword">client</span>.csr  </span><br><span class="line">openssl ca -in <span class="keyword">client</span>.csr -out <span class="keyword">client</span>.crt -cert ca.crt -keyfile ca.key</span><br><span class="line">免密钥启动同上，TXT_DB error number <span class="number">2</span> 异常请参考 openssl TXT_DB error number <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p>生成pem格式证书<br>有时需要用到pem格式的证书，可以用以下方式合并证书文件（crt）和私钥文件（key）来生成</p>
<figure class="highlight axapta"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$cat <span class="keyword">client</span>.crt <span class="keyword">client</span>.key&gt; <span class="keyword">client</span>.pem</span><br><span class="line">$cat <span class="keyword">server</span>.crt <span class="keyword">server</span>.key &gt; <span class="keyword">server</span>.pem</span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
<li><p>Nginx、Tomcat配置HTTPS</p>
<p>nginx.conf添加</p>
<figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">   <span class="attribute">listen</span>       <span class="number">443</span> ssl;</span><br><span class="line">   <span class="attribute">server_name</span>  localhost;</span><br><span class="line"></span><br><span class="line">   <span class="attribute">ssl_certificate</span>      /work/openssl/single/server.crt;</span><br><span class="line">   <span class="attribute">ssl_certificate_key</span>  /work/openssl/single/server.key.unsecure;</span><br><span class="line"></span><br><span class="line">   <span class="attribute">ssl_session_cache</span>    shared:SSL:<span class="number">1m</span>;</span><br><span class="line">   <span class="attribute">ssl_session_timeout</span>  <span class="number">5m</span>;</span><br><span class="line">   <span class="attribute">ssl_ciphers</span>  HIGH:!aNULL:!MD5;</span><br><span class="line">   <span class="attribute">ssl_prefer_server_ciphers</span>  <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line">   <span class="attribute">location</span> / &#123;</span><br><span class="line">            <span class="attribute">allow</span> all;</span><br><span class="line">            <span class="attribute">proxy_pass</span> https://192.168.1.121:443;</span><br><span class="line">            <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">            <span class="attribute">proxy_set_header</span> Upgrade <span class="variable">$http_upgrade</span>;</span><br><span class="line">            <span class="attribute">proxy_set_header</span> Connection <span class="string">"upgrade"</span>;</span><br><span class="line">            <span class="attribute">proxy_set_header</span> X-Real-Ip <span class="variable">$remote_addr</span>;</span><br><span class="line">            <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line">            <span class="attribute">proxy_set_header</span> X-Forwarded-Proto <span class="variable">$scheme</span>;</span><br><span class="line">   &#125;</span><br></pre></td></tr></table></figure>

<p>tomcat server.xml添加</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;Connector <span class="attribute">port</span>=<span class="string">"8443"</span> <span class="attribute">protocol</span>=<span class="string">"org.apache.coyote.http11.Http11AprProtocol"</span></span><br><span class="line">               <span class="attribute">maxThreads</span>=<span class="string">"150"</span> <span class="attribute">SSLEnabled</span>=<span class="string">"true"</span> <span class="attribute">scheme</span>=<span class="string">"https"</span> <span class="attribute">secure</span>=<span class="string">"true"</span></span><br><span class="line">               <span class="attribute">clientAuth</span>=<span class="string">"false"</span> <span class="attribute">SSLCertificateFile</span>=<span class="string">"/work/openssl/single/server.crt"</span> <span class="attribute">SSLProtocol</span>=<span class="string">"SSLv2+SSLv3+TLSv1"</span></span><br><span class="line">          <span class="attribute">SSLCertificateKeyFile</span>=<span class="string">"/work/openssl/single/server.key.unsecure"</span> <span class="attribute">SSLVerifyClient</span>=<span class="string">"optional"</span>/&gt;</span><br></pre></td></tr></table></figure>
<p>server.xml默认注释了</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;Connector <span class="attribute">port</span>=<span class="string">"8443"</span> <span class="attribute">protocol</span>=<span class="string">"org.apache.coyote.http11.Http11NioProtocol"</span></span><br><span class="line">               <span class="attribute">maxThreads</span>=<span class="string">"150"</span> <span class="attribute">SSLEnabled</span>=<span class="string">"true"</span> <span class="attribute">scheme</span>=<span class="string">"https"</span> <span class="attribute">secure</span>=<span class="string">"true"</span></span><br><span class="line">               <span class="attribute">clientAuth</span>=<span class="string">"false"</span> <span class="attribute">sslProtocol</span>=<span class="string">"TLS"</span> /&gt;</span><br></pre></td></tr></table></figure>
<p>需要注意protocol中的 Http11AprProtocol 与 Http11NioProtocol，加密算法不支持的话，可能报异常 <code>Java and SSL - java.security.NoSuchAlgorithmException</code></p>
</li>
<li><p>一个大坑</p>
<p>Ubuntu上跑Tengine，代理Windows上的应用，访问HTTPS页面时候总是报504错误，后来又报502错误。</p>
<p>排查了一个多小时后发现是Windows系统安装了Vmware Workstation，而Vmware的VMware Authorization Service自动启动了。</p>
<p>还有另外一个Vmware的服务忘记了，这两个服务会影响本地应用使用HTTPS，所以停止掉或禁用掉就可以了。</p>
<p><a href="http://tool.chinaz.com/pagestatus/" target="_blank" rel="noopener">HTTP状态码</a></p>
<blockquote><p>502 作为网关或者代理工作的服务器尝试执行请求时，从上游服务器接收到无效的响应。</p>
<p>504 作为网关或者代理工作的服务器尝试执行请求时，未能及时从上游服务器（URI标识出的服务器，例如HTTP、FTP、LDAP）或者辅助服务器（例如DNS）收到响应。 　　注意：某些代理服务器在DNS查询超时时会返回400或者500错误</p>
</blockquote>

</li>
</ol>
<p>参考资料：</p>
<ul>
<li><a href="http://my.oschina.net/itblog/blog/651434" target="_blank" rel="noopener">OpenSSL生成根证书CA及签发子证书</a></li>
<li><a href="http://my.oschina.net/u/658145/blog/75093" target="_blank" rel="noopener">Windows下Tomcat+nginx配置证书实现登录页https访问</a></li>
<li><a href="http://itindex.net/detail/50701-tomcat-bio-nio.apr" target="_blank" rel="noopener">Tomcat 的三种(bio,nio.apr) 高级 Connector 运行模式</a></li>
<li><a href="http://blog.csdn.net/na_tion/article/details/17334669" target="_blank" rel="noopener">Nginx部署部分https与部分http</a></li>
<li><a href="https://iyaozhen.com/nginx-https-conf.html" target="_blank" rel="noopener">Nginx HTTPS 配置实践</a></li>
</ul>

    </div>

    
    
    

      <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/web/" rel="tag"># web</a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2016/07/28/ubuntu-desktop-boot-to-char-interface/" rel="prev" title="Ubuntu Desktop 16.04 设置默认启动到字符界面">
      <i class="fa fa-chevron-left"></i> Ubuntu Desktop 16.04 设置默认启动到字符界面
    </a></div>
      <div class="post-nav-item">
    <a href="/2016/09/25/java-cacerts-import-certificate/" rel="next" title="Java cacerts 证书库导入自签名证书">
      Java cacerts 证书库导入自签名证书 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  

  </div>


          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let activeClass = CONFIG.comments.activeClass;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="laudukang"
      src="/images/head.png">
  <p class="site-author-name" itemprop="name">laudukang</p>
  <div class="site-description" itemprop="description">Bug Not Found</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">68</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">10</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">25</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>
  <div class="links-of-author motion-element">
      <span class="links-of-author-item">
        <a href="https://github.com/laudukang" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;laudukang" rel="noopener" target="_blank"><i class="fa fa-fw fa-github"></i>GitHub</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://gitee.com/laudukang" title="Gitee → https:&#x2F;&#x2F;gitee.com&#x2F;laudukang" rel="noopener" target="_blank"><i class="fa fa-fw fa-github-alt"></i>Gitee</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://stackoverflow.com/users/5621049/laudukang" title="StackOverflow → https:&#x2F;&#x2F;stackoverflow.com&#x2F;users&#x2F;5621049&#x2F;laudukang" rel="noopener" target="_blank"><i class="fa fa-fw fa-stack-overflow"></i>StackOverflow</a>
      </span>
      <span class="links-of-author-item">
        <a href="https://www.google.com/maps/place/%E6%B7%B1%E5%9C%B3%E5%B8%82%E8%BD%AF%E4%BB%B6%E4%BA%A7%E4%B8%9A%E5%9F%BA%E5%9C%B0/@22.5244896,113.9382973,17z/data=!3m1!4b1!4m5!3m4!1s0x3403ee17d008a019:0xbb7b06b73d856c14!8m2!3d22.5244896!4d113.9382973" title="Map → https:&#x2F;&#x2F;www.google.com&#x2F;maps&#x2F;place&#x2F;%E6%B7%B1%E5%9C%B3%E5%B8%82%E8%BD%AF%E4%BB%B6%E4%BA%A7%E4%B8%9A%E5%9F%BA%E5%9C%B0&#x2F;@22.5244896,113.9382973,17z&#x2F;data&#x3D;!3m1!4b1!4m5!3m4!1s0x3403ee17d008a019:0xbb7b06b73d856c14!8m2!3d22.5244896!4d113.9382973" rel="noopener" target="_blank"><i class="fa fa-fw fa-map-marker"></i>Map</a>
      </span>
  </div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

<div class="copyright">
  
  &copy; 2015 – 
  <span itemprop="copyrightYear">2025</span>
  <span class="with-love">
    <i class="fa fa-heart icon-next-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">laudukang</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> 强力驱动 v4.2.0
  </div>
  <span class="post-meta-divider">|</span>
  <div class="theme-info">主题 – <a href="https://muse.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Muse</a> v7.7.1
  </div>

        
<div class="busuanzi-count">
  <script pjax async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
</div>






  <script pjax>
  function leancloudSelector(url) {
    url = encodeURI(url);
    return document.getElementById(url).querySelector('.leancloud-visitors-count');
  }
  if (CONFIG.page.isPost) {
    function addCount(Counter) {
      var visitors = document.querySelector('.leancloud_visitors');
      var url = decodeURI(visitors.getAttribute('id'));
      var title = visitors.getAttribute('data-flag-title');

      Counter('get', `/classes/Counter?where=${JSON.stringify({ url })}`)
        .then(response => response.json())
        .then(({ results }) => {
          if (results.length > 0) {
            var counter = results[0];
              leancloudSelector(url).innerText = counter.time + 1;
            Counter('put', '/classes/Counter/' + counter.objectId, { time: { '__op': 'Increment', 'amount': 1 } })
              .then(response => response.json())
              .catch(error => {
                console.error('Failed to save visitor count', error);
              })
          } else {
              Counter('post', '/classes/Counter', { title: title, url: url, time: 1 })
                .then(response => response.json())
                .then(() => {
                  leancloudSelector(url).innerText = 1;
                })
                .catch(error => {
                  console.error('Failed to create', error);
                });
          }
        })
        .catch(error => {
          console.error('LeanCloud Counter Error', error);
        });
    }
  } else {
    function showTime(Counter) {
      var visitors = document.querySelectorAll('.leancloud_visitors');
      var entries = [...visitors].map(element => {
        return decodeURI(element.getAttribute('id'));
      });

      Counter('get', `/classes/Counter?where=${JSON.stringify({ url: { '$in': entries } })}`)
        .then(response => response.json())
        .then(({ results }) => {
          if (results.length === 0) {
            document.querySelectorAll('.leancloud_visitors .leancloud-visitors-count').forEach(element => {
              element.innerText = 0;
            });
            return;
          }
          for (let item of results) {
            let { url, time } = item;
            leancloudSelector(url).innerText = time;
          }
          for (let url of entries) {
            var element = leancloudSelector(url);
            if (element.innerText == '') {
              element.innerText = 0;
            }
          }
        })
        .catch(error => {
          console.error('LeanCloud Counter Error', error);
        });
    }
  }

  fetch('https://app-router.leancloud.cn/2/route?appId=CPfRDhOlTyfkHW155W3Kx3H1-gzGzoHsz')
    .then(response => response.json())
    .then(({ api_server }) => {
      var Counter = (method, url, data) => {
        return fetch(`https://${api_server}/1.1${url}`, {
          method: method,
          headers: {
            'X-LC-Id': 'CPfRDhOlTyfkHW155W3Kx3H1-gzGzoHsz',
            'X-LC-Key': 'TX05RQSQMd8fbL7RaJNADS7S',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(data)
        });
      };
      if (CONFIG.page.isPost) {
        if (CONFIG.hostname !== location.hostname) return;
        addCount(Counter);
      } else if (document.querySelectorAll('.post-title-link').length >= 1) {
        showTime(Counter);
      }
    });
  </script>


      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/pjax/pjax.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js"></script>
  <script src="//cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/muse.js"></script>


<script src="/js/next-boot.js"></script>

  <script>
var pjax = new Pjax({
  selectors: [
    'head title',
    '#page-configurations',
    '.content-wrap',
    '.post-toc-wrap',
    '#pjax'
  ],
  switches: {
    '.post-toc-wrap': Pjax.switches.innerHTML
  },
  analytics: false,
  cacheBust: false,
  scrollTo : !CONFIG.bookmark.enable
});

window.addEventListener('pjax:success', () => {
  document.querySelectorAll('script[pjax], script#page-configurations, #pjax script').forEach(element => {
    var code = element.text || element.textContent || element.innerHTML || '';
    var parent = element.parentNode;
    parent.removeChild(element);
    var script = document.createElement('script');
    if (element.id) {
      script.id = element.id;
    }
    if (element.className) {
      script.className = element.className;
    }
    if (element.type) {
      script.type = element.type;
    }
    if (element.src) {
      script.src = element.src;
      // Force synchronous loading of peripheral JS.
      script.async = false;
    }
    if (element.getAttribute('pjax') !== null) {
      script.setAttribute('pjax', '');
    }
    if (code !== '') {
      script.appendChild(document.createTextNode(code));
    }
    parent.appendChild(script);
  });
  NexT.boot.refresh();
  // Define Motion Sequence & Bootstrap Motion.
  if (CONFIG.motion.enable) {
    NexT.motion.integrator
      .init()
      .add(NexT.motion.middleWares.subMenu)
      .add(NexT.motion.middleWares.postList)
      .bootstrap();
  }
  NexT.utils.updateSidebarPosition();
});
</script>




  















    <div id="pjax">
  

  
<script>window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };</script><script defer src="/_vercel/insights/script.js" data-endpoint="/this-is-vercel-insights"></script><script>window.si = window.si || function () { (window.siq = window.siq || []).push(arguments); };</script><script defer src="/_vercel/speed-insights/script.js" data-endpoint="/this-is-vercel-insights-speed"></script>
    </div>
</body>
</html>
